package com.qiu.util.Interceptor;

import java.net.URLDecoder;

import com.power.common.util.StringUtil;
import com.qiu.util.threadLocalVar.ExecuteSqlStatement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.util.ContentCachingRequestWrapper;
import org.springframework.web.util.ContentCachingResponseWrapper;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.stream.Collectors;

public class RequestResponseLoggingInterceptor implements HandlerInterceptor {

    private static final Logger log = LoggerFactory.getLogger(RequestResponseLoggingInterceptor.class);

    // 请求完成后：读取请求体和响应体
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws UnsupportedEncodingException {
        String jsonRequestString = "";
        String jsonResponseString = "";
        String contentType = request.getHeader("Content-Type");
        String satoken = request.getHeader("satoken");
        // 动态获取编码
        StringBuilder urlPathArgs = new StringBuilder();
        //存储url路径的参数，现进行提取
        request.getParameterMap().entrySet().stream()
                .forEach(arg -> {
                    String key = arg.getKey();
                    String[] values = arg.getValue();
                    String decodedValues = Arrays.stream(values)
                            .collect(Collectors.joining(", "));
                    urlPathArgs.append(key).append(": [").append(decodedValues).append("], ");
                });
        //删除最后一个多余的逗号
        if (urlPathArgs.toString().lastIndexOf(',') > 0) {
            urlPathArgs.deleteCharAt(urlPathArgs.toString().lastIndexOf(','));
        }

        // 读取请求体
        if (request instanceof ContentCachingRequestWrapper) {
            try {
                // 手动读取输入流以填充缓存
                ServletInputStream inputStream = request.getInputStream();
                byte[] buffer = new byte[1024];
                while (inputStream.read(buffer) != -1) {
                    // 此处无需处理内容，仅强制读取所有字节
                }
            } catch (IOException e) {
                log.info("请求体已消费，无需二次读取");
            }
            ContentCachingRequestWrapper requestWrapper = (ContentCachingRequestWrapper) request;
            jsonRequestString = new String(requestWrapper.getContentAsByteArray(), request.getCharacterEncoding());
            if (StringUtil.isNotEmpty(contentType) && contentType.equals("application/x-www-form-urlencoded")) {
                jsonRequestString = URLDecoder.decode(jsonRequestString, StandardCharsets.UTF_8.name());
            }
        }
        // 读取响应体
        if (response instanceof ContentCachingResponseWrapper) {
            ContentCachingResponseWrapper responseWrapper = (ContentCachingResponseWrapper) response;
            jsonResponseString = new String(responseWrapper.getContentAsByteArray(), response.getCharacterEncoding());
        }
        if (!request.getMethod().equals("OPTIONS")) {
            log.info("\n============执行信息============:" +
                    "\n请求路径:【{}】" +
                    "\n请求方法类型:【{}】" +
                    "\nContent-Type:【{}】" +
                    "\nsatoken:【{}】" +
                    "\n请求路径携带的参数:【{}】" +
                    "\n============分隔符============" +
                    "\n请求体:{}" +
                    "\n执行的SQL语句:{}" +
                    "\n响应体:{}" +
                    "\n============结束============", request.getRequestURI(), request.getMethod(), contentType, satoken, urlPathArgs, jsonRequestString, ExecuteSqlStatement.getLocalVar().get(), jsonResponseString);
        }
        ExecuteSqlStatement.getLocalVar().remove();
    }

}